package com.hk.commons.utils.sys;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.commons.lang.ArrayUtils;

public class DateWeekOrHoliday {

	// @Value("${holidays}")
	// private String holidays;
	//public static final String holidays = "2016-06-09,2016-06-10,2016-06-11,2016-09-15,2016-09-16,2016-09-17,2016-10-01,2016-10-02,2016-10-03,2016-10-04,2016-10-05,2016-10-06,2016-10-07";

	public static final String holidays = "2016-06-09,2016-06-10,2016-06-11,2016-09-15,2016-09-16,2016-09-17,2016-10-01,2016-10-02,2016-10-03,2016-10-04,2016-10-05,2016-10-06,2016-10-07," +
			"2017-01-27,2017-01-28,2017-01-29,2017-01-30,2017-01-31,2017-02-01,2017-02-02,2017-04-02,2017-04-03,2017-04-04,2017-05-01,2017-05-29,2017-05-30,2017-10-02,2017-10-03,2017-10-04,2017-10-05,2017-10-06,2017-10-07,2017-10-08";

	/**
	 * 获得收益时间(获取当前天+1天，周末不算).
	 *
	 * @param date
	 *            任意日期 qryType:0固收 1基金
	 * @return the income date
	 * @throws NullPointerException
	 *             if null == date
	 * 
	 */

	/*
	 * 基金的交易时间就是股票的交易时间，每天上午9：30到下午3：00。
	 * 3点钱购买，当天确认，第二天开始产生收益；3点后购买，t+1日才算购买，t+2日算收益
	 */
	public static Date getIncomeDate(Date date, int qryType)
			throws NullPointerException {
		if (null == date) {
			throw new NullPointerException("the date is null or empty!");
		}

		// 对日期的操作,我们需要使用 Calendar 对象
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		if (qryType == 0) {// 固定收益
			// +1天
			calendar.add(Calendar.DAY_OF_MONTH, +1);
		} else {// 基金算时间
			int hour = calendar.get(Calendar.HOUR_OF_DAY);
			if (hour >= 9 && hour <= 15) {// 交易时间
				calendar.add(Calendar.DAY_OF_MONTH, +1);
			} else {
				calendar.add(Calendar.DAY_OF_MONTH, +2);
			}
		}

		// //+1天
		// calendar.add(Calendar.DAY_OF_MONTH, +1);

		Date incomeDate = calendar.getTime();

		if (isWeekend(calendar) || isHoliday(calendar)) {
			// 递归
			return getIncomeDate(incomeDate, qryType);
		}
		return incomeDate;
	}

	public static Calendar getIncomeCalendar(Calendar calendar, int qryType)
			throws NullPointerException {
		if (null == calendar) {
			throw new NullPointerException("the calendar is null or empty!");
		}

		if (qryType == 0) {// 固定收益
			// +1天
			calendar.add(Calendar.DAY_OF_MONTH, +1);
		} else {// 基金算时间
			int hour = calendar.get(Calendar.HOUR_OF_DAY);
			if (hour >= 9 && hour <= 15) {// 交易时间
				calendar.add(Calendar.DAY_OF_MONTH, +1);
			} else {
				calendar.add(Calendar.DAY_OF_MONTH, +2);
			}
		}

		if (isWeekend(calendar) || isHoliday(calendar)) {
			// 递归
			return getIncomeCalendar(calendar, qryType);
		}
		return calendar;
	}

	/**
	 * 判断一个日历是不是周末.
	 *
	 * @param calendar
	 *            the calendar
	 * @return true, if checks if is weekend
	 */
	public static boolean isWeekend(Calendar calendar) {
		// 判断是星期几
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

		if (dayOfWeek == 1 || dayOfWeek == 7) {
			return true;
		}
		return false;
	}

	/**
	 * 一个日历是不是节假日.
	 *
	 * @param calendar
	 *            the calendar
	 * @return true, if checks if is holiday
	 */
	public static boolean isHoliday(Calendar calendar) {

		String pattern = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
		String dateString = simpleDateFormat.format(calendar.getTime());
		System.out.println(dateString);
		// 节假日 这个可能不同地区,不同年份 都有可能不一样,所以需要有个地方配置, 可以放数据库, 配置文件,环境变量 等等地方
		// 这里以配置文件 为例子
		// String
		// holidays="2016-06-09,2016-06-10,2016-06-11,2016-09-15,2016-09-16,2016-09-17,2016-10-02,2016-10-03,2016-10-04,2016-10-05,2016-10-06,2016-10-07"+
		// "2017-01-01,2017-01-02,2017-01-03";

		String[] holidayArray = holidays.split(",");

		boolean isHoliday = ArrayUtils.contains(holidayArray,
				dateString.substring(0, 10));
		return isHoliday;
	}

	public static Boolean afterDay(Calendar a, Calendar b) {
		Calendar daya = Calendar.getInstance();
		daya.set(a.get(Calendar.YEAR), a.get(Calendar.MONTH),
				a.get(Calendar.DAY_OF_MONTH));
		Calendar dayb = Calendar.getInstance();
		dayb.set(b.get(Calendar.YEAR), b.get(Calendar.MONTH),
				b.get(Calendar.DAY_OF_MONTH));
		daya.add(Calendar.DAY_OF_YEAR, +1);
		if ((daya.get(Calendar.YEAR) == daya.get(Calendar.YEAR))
				&& (daya.get(Calendar.MONTH) == daya.get(Calendar.MONTH))
				&& (daya.get(Calendar.DAY_OF_MONTH) == daya
						.get(Calendar.DAY_OF_MONTH))) {
			return true;
		} else {
			return false;
		}

	}

	public static Boolean ifLongger(Calendar a, Calendar b) {// a>=b
		int aYear = a.get(Calendar.YEAR);
		int aMonth = a.get(Calendar.MONTH);
		int aDay = a.get(Calendar.DAY_OF_MONTH);
		int bYear = b.get(Calendar.YEAR);
		int bMonth = b.get(Calendar.MONTH);
		int bDay = b.get(Calendar.DAY_OF_MONTH);
		if (aYear > bYear) {
			return true;
		} else if (aYear == bYear) {
			if (aMonth > bMonth) {
				return true;
			} else if (aMonth == bMonth) {
				if (aDay > bDay) {
					return true;
				} else if (aDay == bDay) {
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	/**
	 * 获取今天之后第n个T day
	 * 
	 * @param n
	 * @return
	 */
	// for (int i = 0; i < n;) {
	// Long nextDayTime = getNextDD(n);
	// cal.setTimeInMillis(nextDayTime);
	// System.out.println(DateUtil.transferLongToDate("yyyyMMddHHmmss",
	// nextDayTime));//
	// // 如果是节假日则 T日增加i++
	// if (isHoliday(cal)) {
	// i++;
	// }
	// }
	public static Long getNextTD(Calendar cal, int n) {
		Long nextDayTime = getNextDD(cal, n);// 获得第n天后的时间
		cal.setTimeInMillis(nextDayTime);
		// 如果n天后是节假日，往后推。
		while (isHoliday(cal)) {
			cal.setTimeInMillis(getNextDD(cal, 1));
		}
		cal.set(Calendar.HOUR_OF_DAY, 12);
		cal.set(Calendar.MINUTE, 00);
		cal.set(Calendar.SECOND, 00);
		cal.set(Calendar.MILLISECOND, 000);
		return cal.getTimeInMillis();
	}

	/**
	 * 获取今天之后第n个D day
	 * 
	 * @return
	 */
	public static Long getNextDD(Calendar cal, int n) {
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) + n);
		cal.set(Calendar.HOUR_OF_DAY, 12);
		cal.set(Calendar.MINUTE, 00);
		cal.set(Calendar.SECOND, 00);
		cal.set(Calendar.MILLISECOND, 000);

		return cal.getTimeInMillis();
	}

	/**
	 * 根据传入的参数计算下一个日期
	 * 
	 * @param cal
	 * @param n
	 * @return
	 */
	public static Long getNextD(Long time, int n) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(time);

		cal.set(Calendar.DATE, cal.get(Calendar.DATE) + n);
		cal.set(Calendar.HOUR_OF_DAY, 12);
		cal.set(Calendar.MINUTE, 00);
		cal.set(Calendar.SECOND, 00);
		cal.set(Calendar.MILLISECOND, 000);
		return cal.getTimeInMillis();
	}

}
